# Tags Tab module for CROSS

#########################################################################################
#
# Copyright (C) 2008  
# Authors: Aljosa Osep (aljosa.osep@gmail.com), Jernej Kranjec (jernej.kranjec@gmail.com)
# From Faculty of Electrical Engineering and Computer Science, Maribor, Slovenia
# Done at School of Technology, Seinajoki, Finland
# Under mentor Kimmo Salmenjoki (kimmo.salmenjoki@seamk.fi)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################################

# ==================== imports ====================== #
import sys
sys.path.append('Modules/GUI/Widgets')
sys.path.append('Modules/Core')


import pygtk            # import pygtk library
pygtk.require('2.0')    # require version 2.o
import gtk 	        # import gtk

import tabModule	# import abstract tab class
import tabWidgetsModule # custom widgets used here
import HDLC		# command parser


############################
# commandTab class
############################
class tagsTab(tabModule.abstractTab):

	# methods
	def ascii_to_hex(self, string):
		hexn = ""
		for char in string:
			hexn = hexn + hex(ord(char))[2:]
		return hexn

	def hex_to_ascii(self, number):
		ascii = ""
		i = 0 
		while i < len(number)-1:
			decimal = int(number[i] + number[i+1], 16)
			if decimal > 31 and decimal < 127:
				ascii = ascii + str(unichr(decimal))
			i = i+2
		return unicode(ascii, "utf-8")


	# callbacks
	# ================= EXECUTE button callback ==================== #
	def execute_button_callback(self):
		gen_str = "}Ra,a:" +  self.read_frame.controls[1].get_entry().get_text()  	# start generating string
		gen_str = gen_str + ",l:" + self.read_frame.controls[2].get_entry().get_text() 	# add num_of_blocks setting
		gen_str = gen_str + "!"								# finish string

		# generate string
		self.gen_str_lbl.set_text("Generated string: " + gen_str.replace('\n',' '))	# append it to label
		self.communicator.sendData(gen_str + '\r\n')					# and send it to communicator
	
		inputData = self.communicator.retriveData()					# retrieve data from comm
		self.rt_str_lbl.set_text("Returned string: " + inputData.replace('\n',' '))	# set rtr_str to label

		tt = HDLC.CHUMP().parse(inputData)						# parse retireved data

		if tt.has_key("d:"):								# if tag id is avalible
			self.read_frame.controls[0].enable()					# enable control
			self.read_frame.controls[0].set_entry_text(tt["d:"])			# and set data to label
			self.write_frame.controls[0].set_entry_text(tt["d:"])	
		else:
			self.read_frame.controls[0].disable()					# otherwise disable widget

		if tt.has_key("a:"):								# address is given
			self.read_frame.controls[1].set_entry_text(tt["a:"])		


		if tt.has_key("b:"):								# if tag id is avalible
			self.read_frame.controls[3].enable()					# enable control
			if self.read_frame.controls[4].get_mode() == 1:				# mode 1: ASCII mode
				data = self.hex_to_ascii(tt["b:"])				# data = data converted to ascii		
			else:
				data = tt["b:"]							# data is not converted to ascii, pure hex
			self.read_frame.controls[3].set_entry_text(data)			# and set data to label	

			if self.write_frame.controls[4].get_mode() == 1:			# mode 1: ASCII mode
				data = self.hex_to_ascii(tt["b:"])				# data = data converted to ascii
			else:
				data = tt["b:"]							# data is not converted to ascii, pure hex
			self.write_frame.controls[3].set_entry_text(data)			# and set data to label

		else:
			self.read_frame.controls[3].disable()					# otherwise disable widget

	#	if tt.has_key("b:"):
	#		self.read_frame.controls[4].set_entry_text(tt["b:"])

		if tt.has_key("t:"):								# if tag id is avalible
			self.read_frame.controls[5].enable()					# enable control
			self.read_frame.controls[5].set_entry_text(tt["t:"])			# and set data to label
		else:
			self.read_frame.controls[5].disable()					# otherwise disable widget
			
		if tt.has_key("checksum:"):
			
			if HDLC.CHUMP().verifyChecksum(inputData):
				self.read_frame.controls[6].set_entry_text("OK (" + tt["checksum:"] + ")")
			else:
				self.read_frame.controls[6].set_entry_text("FAIL (" + tt["checksum:"] + ")")
				
			self.read_frame.controls[6].disable()
		else:
			self.read_frame.controls[6].set_entry_text("")
			self.read_frame.controls[6].disable()


	# ================= APPLY button callback ==================== #
	def apply_button_callback(self):
		# Wa ... any tag
		# Wt ... specific tag

		# EPC0 : Wa, Wt
		# EPC1 : Wa
		# IS186B : Wt

		if self.write_frame.controls[5].combo.get_active() == 2:
			gen_str = "}Wa,"
		#	self.write_frame.controls[0].disable()
		elif self.write_frame.controls[5].combo.get_active() == 0:
			gen_str = "}Wt,"
		#	self.write_frame.controls[0].enable()
		elif self.write_frame.controls[5].combo.get_active() == 1:
			if self.write_frame.controls[0].get_entry_text() == "<any>":			
				gen_str = "}Wa,"
		#		self.write_frame.controls[0].disable()
			else:
				gen_str = "}Wt,"
		#		self.write_frame.controls[0].enable()
		else:
			return

		# append data
		if self.write_frame.controls[4].get_mode() == 1:	# ascii
			data = self.ascii_to_hex(self.write_frame.controls[3].get_entry_text())
		#	self.hex_to_ascii("123456")
		else: # hex
			data = 	self.write_frame.controls[3].get_entry_text()
		# convert to hex
		gen_str = gen_str + "b:" + data + ","

		# append block address
		gen_str = gen_str + "a:" + self.write_frame.controls[1].get_entry_text() + ","

		# append block address
		gen_str = gen_str + "l:" + self.write_frame.controls[2].get_entry_text() + ""

		# append protocol specific data 
		if self.write_frame.controls[5].get_entry_text() == "EPC0" or self.write_frame.controls[5].get_entry_text() == "EPC1":
					gen_str = gen_str + ",f:2"		

		# finish string
		gen_str = gen_str + "!"

		self.gen_str_lbl.set_text("Generated string: " + gen_str.replace('\n',' '))		# append it to label
		self.communicator.sendData(gen_str+'\r\n')						
		
		returnData = self.communicator.retriveData()
		
		self.rt_str_lbl.set_text("Returned string: " + returnData.replace('\n',' '))
		
		dd = HDLC.CHUMP().parse(returnData)						# parse retireved data
		
		if dd.has_key("checksum:"):
			if dd.has_key("e:"):
				self.write_frame.controls[6].set_entry_text("FAIL")
				self.write_frame.controls[6].disable()
			else :
				self.write_frame.controls[6].set_entry_text("OK")
				self.write_frame.controls[6].disable()
		else:
			self.write_frame.controls[6].set_entry_text("")
			self.write_frame.controls[6].disable()
		
	def clr_button_callback(self, frame):
		frame.clear()


	# initialisation
	def __init__(self, communicator):
		# comm
		self.communicator = communicator					# get communicator instance

		self.init_frame()							# init frame
		self.init_table(1, 3, _homogeneous=False)				# init table

		hbox = gtk.HBox(True, 0)						# horizontal box, for frames
#		hbox.set_border_width(10)

		self.table.attach(hbox, 0, 1, 0, 1)					# attach it to table

		self.read_frame = tabWidgetsModule.custom_frame_widget("Read")		# create read frame
		hbox.pack_start(self.read_frame.get_frame(), True, True, 0)		# pack it
		# append widgets to frame
		self.read_frame.append_widget(tabWidgetsModule.singleLine("Tag ID"))		
		self.read_frame.append_widget(tabWidgetsModule.singleLine("Adddress", True, entry_text="00"))	
		self.read_frame.append_widget(tabWidgetsModule.singleLine("Length", True, entry_text="10"))
		self.read_frame.append_widget(tabWidgetsModule.multipleLine("Data"))
		self.read_frame.append_widget(tabWidgetsModule.singleLineRadio("Type"))
		self.read_frame.append_widget(tabWidgetsModule.singleLine("Tag type"))
		self.read_frame.append_widget(tabWidgetsModule.singleLine("CRC", entry_text=""))
		self.read_frame.append_widget(tabWidgetsModule.singleLineButtons(self.execute_button_callback, self.clr_button_callback, self.read_frame, stock_1=gtk.STOCK_EXECUTE))
		self.read_frame.pack_controls()						# pack all apended widgets to frame
		
		self.read_frame.controls[6].disable()				# quick fix for disabling crc input box

		self.write_frame = tabWidgetsModule.custom_frame_widget("Write")		# create write frame
		hbox.pack_start(self.write_frame.get_frame(), True, True, 0)			# pack it
		# append widgets to frame
		self.write_frame.append_widget(tabWidgetsModule.tagIdWidget("Tag ID", editable=True, entry_text="<any>"))
		self.write_frame.append_widget(tabWidgetsModule.singleLine("Adddress", editable=True, entry_text="00"))
		self.write_frame.append_widget(tabWidgetsModule.singleLine("Length", editable=True, entry_text="10"))
		self.write_frame.append_widget(tabWidgetsModule.multipleLine("Data", editable=True))
		self.write_frame.append_widget(tabWidgetsModule.singleLineRadio("Type"))
		self.write_frame.append_widget(tabWidgetsModule.singleLineCombo("Standard", self.write_frame.controls[0], editable=True))
		self.write_frame.append_widget(tabWidgetsModule.singleLine("CRC", entry_text=""))
		self.write_frame.append_widget(tabWidgetsModule.singleLineButtons(self.apply_button_callback, self.clr_button_callback, self.write_frame, stock_1=gtk.STOCK_APPLY))
		self.write_frame.pack_controls()						# pack all apended widgets to frame
		
		self.write_frame.controls[6].disable()				# quick fix for disabling crc input box

		# generated string label
		self.gen_str_lbl = gtk.Label("Generated string: ")			# create label for generated string
		self.table.attach(self.gen_str_lbl, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 0, 10)	# attach it to table
		self.gen_str_lbl.set_alignment(0,0.1)					# set alignment of text
		self.gen_str_lbl.set_line_wrap(True)
		self.gen_str_lbl.set_single_line_mode(True)
		self.gen_str_lbl.set_max_width_chars(50)
		self.gen_str_lbl.show()							# show label

		# returned command label
		self.rt_str_lbl = gtk.Label("Returned string: ")			# create label for returned string
		self.table.attach(self.rt_str_lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL)	# attach it to table
		self.rt_str_lbl.set_alignment(0,0.1)					# set alignment of text
		self.rt_str_lbl.set_line_wrap(True)
		self.rt_str_lbl.set_single_line_mode(True)
		self.rt_str_lbl.set_max_width_chars(1)
	#	self.rt_str_lbl.set_size_request(100, 55)
		self.rt_str_lbl.show()	

		hbox.show()								# show horizontal box
		self.show_table_frame()							# show table and frame





